#pragma once
#include "Array.h"

class ThreadBase : public wxThread
{
protected:
	wxString m_name;

protected:
	ThreadBase(bool detached = true, const wxString& name = "Unknown ThreadBase")
		: wxThread(detached ? wxTHREAD_DETACHED : wxTHREAD_JOINABLE)
	{
	}

	virtual ~ThreadBase() throw()
	{
		if(IsAlive()) Delete();
	}

	ExitCode Entry()
	{
		Task();
		return (ExitCode)0;
	}

	virtual void Task()=0;

public:
	void Start()
	{
		if(IsAlive()) return;

		if(IsPaused())
		{
			Resume();
		}
		else
		{
			Create();
			Run();
		}
	}
};

template<typename T> class MTPacketBuffer
{
protected:
	volatile bool m_busy;
	volatile u32 m_put, m_get;
	Array<u8> m_buffer;
	u32 m_max_buffer_size;

	void CheckBusy()
	{
		m_busy = m_put >= m_max_buffer_size;
	}

public:
	MTPacketBuffer(u32 max_buffer_size)
		: m_max_buffer_size(max_buffer_size)
	{
		Flush();
	}

	~MTPacketBuffer()
	{
		Flush();
	}

	void Flush()
	{
		m_put = m_get = 0;
		m_buffer.Clear();
		m_busy = false;
	}

	virtual void Push(const T& v) = 0;
	virtual T Pop() = 0;

	bool HasNewPacket() const { return m_put != m_get; }
	bool IsBusy() const { return m_busy; }
};
